package com.geez.bbl.morpho;

import com.geez.bbl.util.Consumer;
import com.geez.bbl.util.FileUtils;
import com.geez.bbl.util.GeezUtil;
import com.geez.bbl.util.ProjectResources;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author biniam.gebremichael
 * @since 6/28/12
 */
public class MorphoFileReader {
//    public static final File bblWl = ProjectResources.getResourceFile("morpho", "morphoOpenOfficeWL.txt");
   public static final File ooWl = ProjectResources.getResourceFile("morpho", "morphoBblWL.txt");
//    static int total = 0;
//    static int good = 0;
//    static int bad = 0;
    private StatCollector currentWord;
    private ConcurrentMap<String, StatCollector> words = new ConcurrentHashMap<String, StatCollector>();
    ConcurrentMap<String, List<StatCollector>> roots = new ConcurrentHashMap<String, List<StatCollector>>();
    ConcurrentMap<String, Set<StatCollector>> theRoots = new ConcurrentHashMap<String, Set<StatCollector>>();


    public static void main(String[] args) {
        MorphoFileReader morphoFileReader = new MorphoFileReader();
        morphoFileReader.processFile(ooWl);
    //    morphoFileReader.processFile(bblWl);
        morphoFileReader.print();

    }

    private class MorphoConsumer implements Consumer<String> {
        @Override
        public void consume(String message) {
            if (message.indexOf("Word: ") == 0) {
                if (currentWord != null) {
                    words.putIfAbsent(currentWord.getWord(), currentWord);
                }
                currentWord = new StatCollector(GeezUtil.removeLatin(message));
                // System.out.println(currentWord.getWord() + (good++) + ". " + message);
            }

            if (message.indexOf("Word: ") == 1) {
                currentWord = null;
                // System.out.println((bad++) + ". " + message);
            }

            if (currentWord != null) {
                if (message.contains("root: ")) {
                    currentWord.setRoot(GeezUtil.removeLatin(message));
                }
            }

        }
    }

    public void processFile(File BODY) {

        FileUtils.processFile(BODY, new MorphoConsumer());

        getRootTree();
        pickTheRoot();
        getRootTreeByTheRoot();
    }

    //re organize the words by their root
    public void getRootTree() {
        for (StatCollector word : words.values()) {
            if (word.getRoot() != null && !word.getRoot().isEmpty()) {
                for (String root : word.getRoot()) {
                    roots.putIfAbsent(root, new ArrayList<StatCollector>());
                    roots.get(root).add(word);
                }
            }
        }
    }

    // the words pick a root with higher number of children
    public void pickTheRoot() {
        for (StatCollector word : words.values()) {
            if (word.getRoot() != null && !word.getRoot().isEmpty()) {
                String theRoot = null;
                int rootScore = 0;
                for (String root : word.getRoot()) {
                    if (roots.get(root).size() > rootScore) {
                        theRoot = root;
                        rootScore = roots.get(root).size();
                    }
                }
                word.setTheRoot(theRoot);
            }
        }
    }

    // re organize the words again by their preferred root
    public void getRootTreeByTheRoot() {
        for (StatCollector word : words.values()) {
            if (word.getTheRoot() != null) {
                theRoots.putIfAbsent(word.getTheRoot(), new TreeSet<StatCollector>());
                theRoots.get(word.getTheRoot()).add(word);
            }
        }
    }

    //print the final root order
    public void print() {
        int i = 0;
        for (Map.Entry<String, Set<StatCollector>> entry : theRoots.entrySet()) {
         //   Set<StatCollector> ss = entry.getValue();
            List<StatCollector> ss = new ArrayList<StatCollector>(entry.getValue());
            if (ss.size() > 1) {
                System.out.println();
             //   System.out.print((i++) + ". ");
                System.out.print(entry.getKey() + ":");

                   for(int j=0;j< ss.size();j++){
                    String next = ss.get(j).getWord();
                    System.out.print(next+",");
                }
                System.out.print(ss.get(ss.size() - 1).getWord());
            }
        }
    }

}
